﻿/**
* @authors Duong NGUYEN <darl2ng@gmail.com>, Anh NGO <ngocanh.ngo@gmail.com>
* @version 0.9
* Copyright 2010
* 
* The MIT License
* Copyright (c) 2010 <Duong NGUYEN <darl2ng@gmail.com>, Anh NGO <ngocanh.ngo@gmail.com>
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package{

	import c_ResHelper2;
	import c_ResLoader2;
	import com.ng.ResHelp.c_ResLoader;
	import com.ng.ui.cMenu;
	import com.ng.ui.cMenuEntry;
	import com.ng.ui.cPanel;
	import com.ng.utils.c_FileReader;
	import com.ng.utils.c_Notification;
	import com.ng.utils.ctn;
	import fl.controls.ComboBox;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.filesystem.File;
	import flash.system.Security;
	import flash.system.System;
	import flash.ui.Keyboard;
	import XML;
	
	//[SWF(width="1024",height="600",backgroundColor="#FFFFFF",framerate="30")]
	[SWF(width="880",height="615",backgroundColor="#CCCCCC",framerate="30")]
	public class Main extends Sprite{

		var __ResEditor:c_ResEditor;
		var __ResHelper:c_ResHelper2;
		var __ResLoader:c_ResLoader2;
		var __Menu:cMenu;
		var __Properties:c_Properties;
		var __XMLProperties:c_XMLProperties;
		var __mm:c_Notification;
		
		public function Main()  {
			//trace(XML.ignoreComments);
			XML.ignoreComments = false;
			addEventListener(Event.ADDED_TO_STAGE, Init);
			c.Init('default');//else it'll be 'default'
			ctn.Init('default');//else it'll be 'default'
			ctn.SetD1(false);
			//c.e('e');
			c.t('t');
			c.i('i');
			//c.SetD1(true);
			c.SetD2(false);
			c.SetD1(true);
			c.d1('d1');
			c.d2('d2');
		}		
		private function Init(e:Event):void {
			c.d1('Init' + stage.stageWidth + ':' + stage.stageHeight);
			c.d2("sandboxType " + Security.sandboxType);			
			addPanelMenu();
			addPanelOutput();
			addPanelProperties();
			addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
		}
		/**
		 * compute the game directory path so that we could use it to retrieve the external libraries
		 * @param	gamePath
		 * @param	xmlFile
		 * @return
		 */
		private function getGameDirectory(xmlPath: String,  xmlFile: File):String {			
			var f1: File;
			var str:String;			
			if (xmlPath.charAt(xmlPath.length - 1) == '/') {
				xmlPath = xmlPath.substring(0, xmlPath.length - 1);//remove the last '/' if need to
			}					
			if (xmlPath == null || xmlPath.length < 2) {
				//take the current directory, which contains the settings.xml file								
				str = xmlFile.parent.nativePath.toString();
				//xmlFile.nativePath.toString() should contains the settings.xml
				c.d1('xmlPath is null, thus same directory:'+str);
			} else {
				var a:Array = xmlPath.split('/');//TODO: what if '\' is used?
				f1 = xmlFile.parent;
				for (var i:int= 0;i < a.length; i++) {
					f1 = f1.parent;
				}
				str = f1.nativePath.toString();
				c.d1('current directory: '+str);
			}
			return str;
		}
		private function Update(event: Event):void {
			if (__mm) __mm.Update('Total memory: '+ System.totalMemory.toString() +' bytes' );
		}
		private function addPanelMenu():void {
			var panel:cPanel = new cPanel('Menu');
			addChild(panel);
			panel.Position(c_Config.MENU_X,c_Config.MENU_Y);
			panel.Background(c_Config.MENU_HIGHT, c_Config.MENU_WIDTH, c_Config.MENU_BG_COLOR);			
			__Menu = new cMenu();
			__Menu.Position(c_Config.PANEL_MARGIN, c_Config.PANEL_MARGIN);
			var MenuEntrys:Array = new Array();
						
			MenuEntrys.push(new cMenuEntry("Open"));
			MenuEntrys.push(new cMenuEntry("Save"));
			MenuEntrys.push(new cMenuEntry("New"));
			MenuEntrys.push(new cMenuEntry("Delete"));
			MenuEntrys.push(new cMenuEntry("ToFront"));
			MenuEntrys.push(new cMenuEntry("ToBack"));			
			MenuEntrys.push(new cMenuEntry("Unselect"));
			
			for (var i:int = 0; i < MenuEntrys.length;i++ ) {
				__Menu.addChild(MenuEntrys[i]);
			}				
			panel.addChild(__Menu);
			var mm:c_MenuMediator = new c_MenuMediator(__Menu);
			mm.Activate('Open', true);
			
			mm.addEventListener(c_FileReader.FILE_LOADED,OnFileLoaded);
		}
		private function addPanelOutput():void {
			var panel:cPanel = new cPanel("Output");
			addChild(panel);
			panel.Position(c_Config.OUTPUT_X,c_Config.OUTPUT_Y);
			panel.Background(c_Config.OUTPUT_HIGHT, c_Config.OUTPUT_WIDTH, c_Config.OUTPUT_BG_COLOR);
			__mm = panel.addChild(new c_Notification(5, 5, panel.width -10, 20));
		}				
		private function addPanelProperties():void {
			__Properties = new c_Properties();
			__Properties.name = 'Properties';
			__Properties.Position(c_Config.PROPERTIES_X,c_Config.PROPERTIES_Y);
			__Properties.scaleX = 0.8;
			__Properties.scaleY = 0.8;		
			this.getChildByName('Menu').addChild(__Properties);
			var pm:c_PropertiesMediator= new c_PropertiesMediator(__Properties);						
		}
		private function addPanelXMLProperties():void {
			trace('addPanelXMLProperties');
			__XMLProperties = new c_XMLProperties();
			__XMLProperties.name = 'XMLProperties';
			__XMLProperties.Position(c_Config.XML_PROPERTIES_X, c_Config.XML_PROPERTIES_Y);
			addChild(__XMLProperties);
			var pm:c_XMLPropertiesMediator= new c_XMLPropertiesMediator(__XMLProperties);
		}
		
		private function addPanelGame(p_width:int, p_height:int):void {
			var gamePanel:cPanel = this.getChildByName('Game');
			if (gamePanel != null) {
				c.d1("Clean old game");
				this.removeChild(gamePanel);				
			}
			var panel:cPanel = new cPanel('Game');
			addChild(panel);			
			panel.Position(c_Config.GAME_X,c_Config.GAME_Y);
			panel.Background(p_width, p_height, c_Config.GAME_BG_COLOR);
			var content:Sprite = new Sprite(); //this Sprite holds the game objects
			content.name = 'Content';
			panel.addChild(content);		
		}
		private function addPanelFramesList():void{
			var cb: ComboBox;
			var s:Sprite;
			var frameIDList: Array;
			var item: Object;
			
			s = getChildByName('FrameList');
			if (s) {
				(s as ComboBox).removeAll();
				removeChild(s);
			}
			cb = new ComboBox();
			cb.prompt = "Frame";
			cb.name = 'FrameList';
			cb.x = c_Config.FRAME_LIST_X;
			cb.y = c_Config.FRAME_LIST_Y;
			cb.addEventListener(Event.CHANGE, OnFrameSelected);
			
			frameIDList = __ResEditor.getAllFrameId();
			var i:uint;
			for (i = 0; i < frameIDList.length; i++) {
				item = new Object();
				item.label = frameIDList[i];
				cb.addItem( item );
				if (cb.selectedItem == null) cb.selectedItem = item;
			}			 
			addChild(cb);
		}			
		private function addPanelClassesListBox():void{			
			var cb: ComboBox;
			var s:Sprite;
			var i:uint;
			var classIDList:Array;
			var item: Object;
			
			s = getChildByName('ClassList');			
			if (s) {				
				(s as ComboBox).removeAll();
				removeChild(s);
			} 
			cb = new ComboBox();
			cb.prompt = "Class";
			cb.name = 'ClassList';
			cb.x = c_Config.CLASS_LIST_X;
			cb.y = c_Config.CLASS_LIST_Y;
			
			classIDList = __ResEditor.classId;
			for (i = 0; i < classIDList.length; i++) {
				item = new Object();
				item.label = classIDList[i];
				cb.addItem( item );
				//cb.selectedItem = item;
				c.d2(item.label);
			}
			item = new Object();
			item.label = 'flash.display.Sprite';
			cb.addItem( item );		
			addChild(cb);
		}		
		private function keyDownHandler(e: KeyboardEvent):void {
			//trace("keyDownHandler"+e.target+':'+e.keyCode+':'+__ResEditor.currentSelect);
			var step: Number = 1;
			var obj: c_ResObject = __ResEditor.currentSelect;

			if (obj != null) {
				switch(e.keyCode){
					case Keyboard.LEFT:
						obj.x -= step;
						__Properties.update(obj);
						break;
					case Keyboard.RIGHT:
						obj.x += step;
						__Properties.update(obj);
						break;
					case Keyboard.UP:
						obj.y -= step;
						__Properties.update(obj);
						break;
					case Keyboard.DOWN:
						obj.y += step;
						__Properties.update(obj);
						break;
				}
			}
		}		
		private function keyUpHandler(e:KeyboardEvent):void {
            //trace("keyUpHandler: " + e.keyCode);
			var obj: c_ResObject = __ResEditor.currentSelect;

			if (obj != null) {
				switch(e.keyCode){
					case Keyboard.LEFT:
					case Keyboard.RIGHT:
					case Keyboard.UP:
					case Keyboard.DOWN:
						__ResEditor.UpdateXML(obj.xml, obj);
						break;
				}
			}			
        }				
		private function OnFrameSelected(e:Event):void {			
			var content:Sprite= this.getChildByName('Game').getChildByName('Content');
			var frameSelect:ComboBox = this.getChildByName('FrameList');
			
			c.d1('OnFrameSelected:' + content);			
			if (content && frameSelect) {
				__ResEditor.CleanUp();
				//remove
				while (content.numChildren > 0) {
					var obj:DisplayObject = content.removeChildAt(0);
					delete(obj);
				}				
				//add
				var sFrame:c_ResObject;
				sFrame =__ResEditor.getFrameById(frameSelect.selectedLabel);
				if (sFrame != null) {
					content.addChild(sFrame);
					sFrame.x = 0;
					sFrame.y = 0;
				}
			}
        }
		private function OnFileLoaded(event:Event):void {
			c.d2(event + ' ' + event.target);
			var fr:c_FileReader; 
			var xmlData: XML;
			var gamePath: String;
			
			fr = (event.currentTarget as c_MenuMediator).FileReader;
			xmlData = new XML(fr.FileData);
			//trace(xmlData);			
			gamePath = getGameDirectory(xmlData.Loadings.Swfs.@xmlPath, fr.file);
			c.d1("gamePath:" + gamePath);
					
			var lw, lh:Number;
			lw = Number(xmlData.Presentation.@width);
			lh = Number(xmlData.Presentation.@height);
			
			if (lw ==0 || lh ==0) {
				lw = stage.stageWidth;
				lh = stage.stageWidth;				
			}			
			c.d1('GamePanel:' + lw + ':' + lh + ' : ' + xmlData.Presentation.@width + ' : ' + xmlData.Presentation.@height);
			
			addPanelGame(lw, lh);
			
			__ResLoader = c_ResLoader2.GetInstance();
			__ResLoader.XMLPath = gamePath;//need to get the relative path
			__ResLoader.initXML(xmlData);			
			__ResLoader.addEventListener(c_ResLoader.EXTERNAL_LIBRARIES_LOADED, OnAutoSWFLoaded);
		}
		private function OnAutoSWFLoaded(e:Event):void {
			c.d1("OnAutoSWFLoaded");
			__ResHelper = c_ResHelper2.GetInstance();			
			__ResHelper.init(__ResLoader);
			__ResEditor = c_ResEditor.GetInstance().Init(__ResHelper);
			
			addPanelFramesList();
			addPanelClassesListBox();
			addPanelXMLProperties();
			trace(__ResLoader.xml);
			__XMLProperties.update(__ResLoader.xml);

			(__Menu.Mediator as c_MenuMediator).ResEditor = __ResEditor;
			__Menu.Mediator.Activate('Save', true);
			
			__Menu.Mediator.Activate('Delete', true);
			__Menu.Mediator.Activate('ToFront', true);
			__Menu.Mediator.Activate('ToBack', true);
			__Menu.Mediator.Activate('Unselect', true);
			
			__Menu.Mediator.ClassList=this.getChildByName('ClassList');
			__Menu.Mediator.Activate('New', true);
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
			
			__ResEditor.addEventListener(c_ResEditor.OBJECT_SELECT, OnObjectSelected);
			
			__Properties.Mediator.ResEditor = __ResEditor;			
			__Properties.Mediator.start();
			
			OnFrameSelected(new Event(Event.CHANGE));			
		}		
		private function OnObjectSelected(e:Event):void {
			c.d2("OnObjectSelected");
			__Properties.update(__ResEditor.currentSelect);
		}		
		
		private function onGotoFrameClick():void {
			c.d2("onGotoFrameClick");
		}		
	}
}